package com.ilink.groundservice.service.impl.study;/**
 * <h3>iLink-java-backend-zhangbo2</h3>
 *
 * @Description <p>学习广场-课程-学生端的服务实现类</p>
 * @Author ZhangBo
 * @Date 2024-09-18 09:33
 **/

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ilink.groundservice.entity.PO.study.course.NoteDocument;
import com.ilink.groundservice.entity.PO.study.course.NoteVideo;
import com.ilink.groundservice.entity.PO.study.course.StudyTeacherCoursesFavorite;
import com.ilink.groundservice.entity.VO.study.CourseResponse;
import com.ilink.groundservice.entity.VO.study.NoteCollectionResponse;
import com.ilink.groundservice.entity.VO.study.NoteResponse;
import com.ilink.groundservice.mapper.study.course.CourseSourceMapper;
import com.ilink.groundservice.mapper.study.course.NoteDocumentMapper;
import com.ilink.groundservice.mapper.study.course.NoteVideoMapper;
import com.ilink.groundservice.mapper.study.course.StudyFileSourceMapper;
import com.ilink.groundservice.mapper.study.course.StudyTeacherCourseMapper;
import com.ilink.groundservice.mapper.study.course.StudyTeacherCoursesFavoriteMapper;
import com.ilink.groundservice.mapper.study.course.StudyTeacherCoursesTeacherMapper;
import com.ilink.groundservice.mapper.study.course.StudyWebSourseMapper;
import com.ilink.groundservice.service.study.StudyCourseStudentService;
import com.ilink.groundservice.service.study.StudyTeacherCoursesFavoriteService;
import com.ilink.ilinkapi.dto.ground.study.CourseMetadataRequest;
import com.ilink.ilinkcommon.domain.PO.studyservice.CourseSource;
import com.ilink.ilinkcommon.domain.PO.studyservice.StudyFileSource;
import com.ilink.ilinkcommon.domain.PO.studyservice.StudyTeacherCourse;
import com.ilink.ilinkcommon.domain.PO.studyservice.StudyTeacherCoursesTeacher;
import com.ilink.ilinkcommon.domain.PO.studyservice.StudyWebSourse;
import com.ilink.ilinkcommon.service.oss.OssService;
import com.ilink.ilinkcommon.utils.SnowflakeIdGenerator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @ClassName StudyCourseStudentServiceImpl
 * @Description
 * @Author ZhangBo
 * @Date 2024-09-18 09:33
 **/
@Service
@Slf4j
@RequiredArgsConstructor
public class StudyCourseStudentServiceImpl extends
    ServiceImpl<StudyTeacherCourseMapper, StudyTeacherCourse> implements StudyCourseStudentService {

    // 文件资源
    private final StudyFileSourceMapper studyFileSourceMapper;
    // 音视频资源
    private final CourseSourceMapper courseSourceMapper;
    // 网页资源
    private final StudyWebSourseMapper studyWebSourseMapper;

    // 课程信息
    private final StudyTeacherCourseMapper studyTeacherCourseMapper;
    // 教师信息
    private final StudyTeacherCoursesTeacherMapper studyTeacherCoursesTeacherMapper;
    // 课程收藏
    private final StudyTeacherCoursesFavoriteService studyTeacherCoursesFavoriteService;
    private final StudyTeacherCoursesFavoriteMapper studyTeacherCoursesFavoriteMapper;

    private final OssService ossService;

    private final NoteVideoMapper noteVideoMapper;
    private final NoteDocumentMapper noteDocumentMapper;

    /**
     * @Author ZhangBo
     * @Description 分页查询学习广场课程元数据
     * @Date 10:51 2024/9/18
     * @Param [userId, request]
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.ilink.groundservice.entity.VO.study.CourseResponse>
     **/
    @Override
    public IPage<CourseResponse> getCourseMetadata(String userId, CourseMetadataRequest request) {
        try{
            int page = request.getPage();
            int size = request.getSize();

            LambdaQueryWrapper<StudyTeacherCourse> queryWrapper = new LambdaQueryWrapper<>();

            // 处理“我收藏的”条件
            if ("我收藏的".equals(request.getCollection())) {
                List<Long> favoriteCourseIds = studyTeacherCoursesFavoriteService.list(
                    new LambdaQueryWrapper<StudyTeacherCoursesFavorite>().eq(StudyTeacherCoursesFavorite::getUserId, userId)
                ).stream().map(StudyTeacherCoursesFavorite::getCourseId).collect(Collectors.toList());

                if (!favoriteCourseIds.isEmpty()) {
                    queryWrapper.in(StudyTeacherCourse::getCourseId, favoriteCourseIds);
                } else {
                    // 如果用户没有收藏任何课程，返回空结果
                    return new Page<>(request.getPage(), size);
                }
            }

            // 处理 keyword 和 tag 的条件
            // 处理关键词查询
            if (request.getKeywords() != null && !request.getKeywords().isEmpty()) {
                queryWrapper.and(wrapper -> wrapper
                        .like(StudyTeacherCourse::getCourseName, request.getKeywords())       // 课程名称中匹配关键词
                        .or()
                        .like(StudyTeacherCourse::getCourseDescription, request.getKeywords()) // 课程描述中匹配关键词
                        .or()
                        .like(StudyTeacherCourse::getCourseTag, request.getKeywords())         // 课程标签中匹配关键词
                );
            }

            if (request.getTag() != null && !request.getTag().isEmpty()) {
                queryWrapper.like(StudyTeacherCourse::getCourseTag, request.getTag());
            }

            // 处理排序条件
            if ("最热".equals(request.getSortBy())) {
                queryWrapper.orderByDesc(StudyTeacherCourse::getViewNum);
            } else if ("最新".equals(request.getSortBy())) {
                queryWrapper.orderByDesc(StudyTeacherCourse::getCreatedAt);
            }

            // 执行分页查询
            IPage<StudyTeacherCourse> studyTeacherCoursePage =
                this.page(new Page<>(page, size), queryWrapper);

            // 将查询结果转换为 CourseResponse 对象
            List<CourseResponse> courseResponses = studyTeacherCoursePage.getRecords().stream()
                .filter(course -> !"知识空间".equals(course.getCourseTag()))
                .map(course -> {
                    CourseResponse response = new CourseResponse();
                    response.setCourseId(course.getCourseId());
                    response.setTeacherId(course.getTeacherId());
                    response.setFolderId(course.getFolderId());
                    response.setCourseName(course.getCourseName());
                    response.setCourseTag(course.getCourseTag());
                    response.setCourseImage(course.getCourseImage() != null
                        ? ossService.getFileUrl(course.getCourseImage())
                        : null);
                    response.setCourseDescription(course.getCourseDescription());
                    response.setViewNum(course.getViewNum());
                    response.setCreatedAt(course.getCreatedAt());

                    // 设置教师信息
                    List<StudyTeacherCoursesTeacher> teachers = studyTeacherCoursesTeacherMapper.selectList(
                        new LambdaQueryWrapper<StudyTeacherCoursesTeacher>().eq(StudyTeacherCoursesTeacher::getCourseId, course.getCourseId())
                    );
                    response.setTeacher(teachers);

                    // 更新每个教师的 teacherImage 为 OSS 中的 URL
                    teachers.forEach(teacher -> {
                        teacher.setTeacherImage(ossService.getFileUrl(teacher.getTeacherImage()));
                    });

                    return response;
                }).collect(Collectors.toList());


            // 返回分页结果
            Page<CourseResponse> courseResponsePage = new Page<>(page, size);
            courseResponsePage.setRecords(courseResponses);
            courseResponsePage.setTotal(studyTeacherCoursePage.getTotal());
            courseResponsePage.setCurrent(studyTeacherCoursePage.getCurrent());
            courseResponsePage.setSize(studyTeacherCoursePage.getSize());

            return courseResponsePage;
        }catch (Exception e){
            log.error("函数getCourseMetadata报错"+e);
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 根据课程id查询学习广场课程信息
     * @Date 10:58 2024/9/18
     * @Param [courseId]
     * @return com.ilink.groundservice.entity.VO.study.CourseResponse
     **/
    @Override
    public CourseResponse getCourseInformationById(Long courseId){
        try {
            // 从数据库中查询课程信息
            StudyTeacherCourse studyTeacherCourse = studyTeacherCourseMapper.selectById(courseId);

            // 如果课程信息不存在，返回 null 或抛出异常
            if (studyTeacherCourse == null) {
                log.error("课程信息未找到 id: " + courseId);
                return null;
            }

            // 将 StudyTeacherCourse 转换为 CourseResponse
            CourseResponse response = new CourseResponse();
            response.setCourseId(studyTeacherCourse.getCourseId());
            response.setTeacherId(studyTeacherCourse.getTeacherId());
            response.setFolderId(studyTeacherCourse.getFolderId());
            response.setCourseName(studyTeacherCourse.getCourseName());
            response.setCourseTag(studyTeacherCourse.getCourseTag());
            response.setCourseDescription(studyTeacherCourse.getCourseDescription());
            response.setViewNum(studyTeacherCourse.getViewNum());
            response.setCreatedAt(studyTeacherCourse.getCreatedAt());
            response.setUpdatedAt(studyTeacherCourse.getUpdatedAt());

            // 设置课程图片 URL，如果存在
            if (studyTeacherCourse.getCourseImage() != null) {
                response.setCourseImage(ossService.getFileUrl(studyTeacherCourse.getCourseImage()));
            }

            // 查询并设置教师信息
            List<StudyTeacherCoursesTeacher> teachers = studyTeacherCoursesTeacherMapper.selectList(
                new LambdaQueryWrapper<StudyTeacherCoursesTeacher>()
                    .eq(StudyTeacherCoursesTeacher::getCourseId, courseId)
            );

            // 更新每个教师的 teacherImage 为 OSS 中的 URL
            teachers.forEach(teacher -> {
                if (teacher.getTeacherImage() != null) {
                    teacher.setTeacherImage(ossService.getFileUrl(teacher.getTeacherImage()));
                }
            });

            response.setTeacher(teachers);

            return response;
        }catch (Exception e){
            log.error("获取课程详细信息错误"+e.getMessage());
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 根据资源id查找资源名称（小链使用）
     * @Date 9:38 2024/9/18
     * @Param [sourceId]
     * @return java.lang.String
     **/
    @Override
    public Map<String, String> getSourceName(Long sourceId) {
       try{
           Map<String, String> result = new HashMap<>();
           StudyFileSource studyFileSource = studyFileSourceMapper.selectById(sourceId);
           if (studyFileSource != null) {
               result.put("资源名称", studyFileSource.getFileName());
               result.put("类型", "文档资源");
               return result;
           }
           CourseSource courseSource = courseSourceMapper.selectById(sourceId);
           if (courseSource != null) {
               result.put("资源名称", courseSource.getFileName());
               result.put("类型", "视频资源");
               return result;
           }
           return null;
       }catch (Exception e){
           log.error("函数getSourceName报错"+e);
           return null;
       }
    }

    /**
     * @Author ZhangBo
     * @Description 根据资源id获取资源URL,包括网页资源
     * @Date 9:52 2024/9/18
     * @Param [sourceId]
     * @return java.lang.String
     **/
    @Override
    public String getSourceUrl(Long sourceId){
        try{
            String filesourcePath = "";
            StudyFileSource studyFileSource = studyFileSourceMapper.selectById(sourceId);
            if(studyFileSource != null)
            {
                filesourcePath = studyFileSource.getFilesourcePath();
            }
            CourseSource studyMediaSource = courseSourceMapper.selectById(sourceId);
            if(studyMediaSource != null){
                filesourcePath = studyMediaSource.getFilesourcePath();
            }
            StudyWebSourse webSourse = studyWebSourseMapper.selectById(sourceId);
            if(webSourse != null){
                return webSourse.getWeb();
            }
            if(Objects.equals(filesourcePath, "")){
                log.error("跳转文件未找到");
                return null;
            }
            if(ossService.getFileUrl(filesourcePath) != null)
            {
                return ossService.getFileUrl(filesourcePath);
            }
            return null;
        }catch (Exception e){
            log.error("函数getSourseUrl报错"+e);
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 根据名称查找视频转写内容
     * @Date 10:15 2024/9/18
     * @Param [objectName]
     * @return java.lang.String
     **/
    @Override
    public String getSourceUrlByObjectName(String objectName){
        try{
            String result = ossService.getFileUrl(objectName);
            if(result != null){
                return result;
            }
            log.error("对象在OSS中未找到");
            return null;
        }catch (Exception e){
            log.error("函数getSourceUrlByObjectName报错"+e);
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 增加点赞量
     * @Date 14:25 2024/9/18
     * @Param [courseId]
     * @return boolean
     **/
    @Override
    @Transactional
    public boolean addView(Long courseId) {
        try {
            StudyTeacherCourse course = studyTeacherCourseMapper.selectById(courseId);
            if (course == null) {
                log.error("没有找到课程" + courseId);
                return false;
            }
            Long viewNum = course.getViewNum();
            course.setViewNum(viewNum+1);
            studyTeacherCourseMapper.updateById(course);
            return true;
        } catch (Exception e) {
            log.error("addView函数错误"+e);
            return false;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 添加课程到用户收藏夹，仅限一次
     * @Date 14:49 2024/9/18
     * @Param [userId, courseId]
     * @return java.lang.String
     **/
    @Override
    @Transactional
    public String addFavoriteCourse(String userId, String courseId){
        try{
            StudyTeacherCoursesFavorite favorite = new StudyTeacherCoursesFavorite();
            // 雪花算法生成的ID
            SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);
            Long favoriteId = idGenerator.nextId();

            Long count = Long.valueOf(studyTeacherCoursesFavoriteMapper.selectCount(
                new LambdaQueryWrapper<StudyTeacherCoursesFavorite>()
                    .eq(StudyTeacherCoursesFavorite::getUserId, userId)
                    .eq(StudyTeacherCoursesFavorite::getCourseId, courseId)
            ));

            // 如果已存在则不插入，直接返回 false 表示未插入
            if (count > 0) {
                log.warn("User '{}' 已收藏 courseId '{}'，跳过插入", userId, courseId);
                return userId+"userId已收藏courseId，跳过插入"+courseId;
            }

            favorite.setFavoriteId(favoriteId);
            favorite.setUserId(userId);
            favorite.setCourseId(Long.valueOf(courseId));

            studyTeacherCoursesFavoriteService.save(favorite);

            return "收藏成功";
        } catch (Exception e){
            log.error("函数addFavoriteCourse报错"+e);
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 取消收藏，仅限一次
     * @Date 14:53 2024/9/18
     * @Param [userId, courseId]
     * @return java.lang.String
     **/
    @Override
    @Transactional
    public String removeFavoriteCourse(String userId, String courseId) {
        try {
            // 查询是否存在该收藏记录
            Long count = Long.valueOf(studyTeacherCoursesFavoriteMapper.selectCount(
                new LambdaQueryWrapper<StudyTeacherCoursesFavorite>()
                    .eq(StudyTeacherCoursesFavorite::getUserId, userId)
                    .eq(StudyTeacherCoursesFavorite::getCourseId, Long.valueOf(courseId))
            ));

            // 如果不存在，则返回相应信息
            if (count == 0) {
                log.warn("User '{}' 没有收藏 courseId '{}'，无法取消收藏", userId, courseId);
                return userId + "没有收藏courseId，无法取消收藏" + courseId;
            }

            // 删除收藏记录
            studyTeacherCoursesFavoriteMapper.delete(
                new LambdaQueryWrapper<StudyTeacherCoursesFavorite>()
                    .eq(StudyTeacherCoursesFavorite::getUserId, userId)
                    .eq(StudyTeacherCoursesFavorite::getCourseId, Long.valueOf(courseId))
            );

            return "取消收藏成功";
        } catch (Exception e) {
            log.error("函数removeFavoriteCourse报错" + e);
            return null;
        }
    }

    /**
     * @Author ZhangBo
     * @Description 获取用户课程收藏夹
     * @Date 15:02 2024/9/18
     * @Param [userId]
     * @return java.util.List<com.ilink.groundservice.entity.PO.study.course.StudyTeacherCoursesFavorite>
     **/
    @Override
    public List<StudyTeacherCoursesFavorite> getFavoriteListByUserId(String userId) {
        return studyTeacherCoursesFavoriteMapper.selectList(
            new LambdaQueryWrapper<StudyTeacherCoursesFavorite>()
                .eq(StudyTeacherCoursesFavorite::getUserId, userId)
        );
    }

    /**
     * @Author ZhangBo
     * @Description 返回最常用的八个标签
     * @Date 16:20 2024/10/8
     * @Param [num]
     * @return java.util.List<java.lang.String>
     **/
    @Override
    public List<String> getCommonTags(int num) {
        return studyTeacherCourseMapper.getCommonTags(num);
    }

    /**
     * @Author ZhangBo
     * @Description 教师获取所有创建课程下的笔记
     * @Date 20:43 2024/10/22
     * @Param [courseId]
     * @return java.util.List<com.ilink.groundservice.entity.VO.study.NoteCollectionResponse>
     **/
    @Override
    public List<NoteCollectionResponse> getAllNotesByTeacher(String courseId) {
        // 1. 根据 courseId 查询所有视频笔记
        List<NoteVideo> videoNotes = noteVideoMapper.selectList(
            new LambdaQueryWrapper<NoteVideo>()
                .eq(NoteVideo::getCourseId, courseId)  // 根据 courseId 查询视频笔记
        );

        // 2. 根据 courseId 查询所有文档笔记
        List<NoteDocument> documentNotes = noteDocumentMapper.selectList(
            new LambdaQueryWrapper<NoteDocument>()
                .eq(NoteDocument::getCourseId, courseId)  // 根据 courseId 查询文档笔记
        );

        // 3. 合并视频笔记和文档笔记结果，返回统一的 NoteResponse 列表
        List<NoteCollectionResponse> allNotes = new ArrayList<>();

        // 处理视频笔记
        if (videoNotes != null) {
            videoNotes.forEach(videoNote -> {
                NoteCollectionResponse noteCollectionResponse = new NoteCollectionResponse();
                noteCollectionResponse.setNoteId(videoNote.getNoteId());
                noteCollectionResponse.setNoteContent(videoNote.getNoteContent());
                noteCollectionResponse.setUserId(videoNote.getUserId());
                noteCollectionResponse.setSourceId(videoNote.getCoursesourceId());
                noteCollectionResponse.setUpdatedAt(videoNote.getUpdatedAt());
                allNotes.add(noteCollectionResponse);
            });
        }

        // 处理文档笔记
        if (documentNotes != null) {
            documentNotes.forEach(documentNote -> {
                NoteCollectionResponse noteCollectionResponse = new NoteCollectionResponse();
                noteCollectionResponse.setNoteId(documentNote.getNoteId());
                noteCollectionResponse.setNoteContent(documentNote.getNoteContent());
                noteCollectionResponse.setUserId(documentNote.getUserId());
                noteCollectionResponse.setSourceId(documentNote.getFilesourceId());
                noteCollectionResponse.setUpdatedAt(documentNote.getUpdatedAt());
                allNotes.add(noteCollectionResponse);
            });
        }

        return allNotes;
    }


}
